package com.lottery.im.module.tim.utils;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Vibrator;
import android.service.notification.StatusBarNotification;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import com.lottery.im.MyApplication;
import com.lottery.im.R;
import com.lottery.im.constant.SpKeyConstant;
import com.lottery.im.module.chat.ui.ChatActivity;
import com.lottery.im.module.main.ui.NotifyActivity;
import com.lottery.im.module.tim.event.MessageEvent;
import com.lottery.im.module.tim.message.CustomMessage;
import com.lottery.im.module.tim.message.GroupTipMessage;
import com.lottery.im.module.tim.message.Message;
import com.lottery.im.module.tim.message.MessageFactory;
import com.lottery.im.module.tim.model.FriendshipInfo;
import com.lottery.im.module.tim.model.GroupInfo;
import com.lottery.im.module.tim.model.NomalConversation;
import com.lottery.im.util.Foreground;
import com.lottery.im.util.SPUtils;
import com.tencent.imsdk.TIMConversation;
import com.tencent.imsdk.TIMConversationType;
import com.tencent.imsdk.TIMGroupReceiveMessageOpt;
import com.tencent.imsdk.TIMMessage;
import com.tencent.imsdk.ext.message.TIMManagerExt;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import me.leolin.shortcutbadger.ShortcutBadger;

/**
 * 在线消息通知展示工具
 *
 * Notification处理方面：Android 8.0 及其以上要做一下特殊处理
 */
public class PushUtil implements Observer {

  private final int pushId = 1;

  private static PushUtil instance = new PushUtil();

  private String channelId ;
  private String channelId1 = "com.lottery.im_channelId.sound" ;
  private String channelId2 = "com.lottery.im_channelId.vibrator" ;
  private String channelDescription = "com.lottery.im_channeldescription";

  private PushUtil() {
    MessageEvent.getInstance().addObserver(this);
  }

  public static PushUtil getInstance() {
    return instance;
  }

  private void PushNotify(TIMMessage msg) {

    //系统消息，自己发的消息，程序在前台的时候不通知
    if (msg == null ||
        (msg.getConversation().getType() != TIMConversationType.Group &&
            msg.getConversation().getType() != TIMConversationType.C2C) ||
        msg.isSelf() ||
        msg.getRecvFlag() == TIMGroupReceiveMessageOpt.ReceiveNotNotify ||
        MessageFactory.getMessage(msg) instanceof CustomMessage) {
      return;
    }

    if (MessageFactory.getMessage(msg).getSummary().equals(GroupTipMessage.NO_TIP_TEXT)){
      return;
    }


    boolean isNotify =
        (boolean) SPUtils.get(MyApplication.getInstance(), SpKeyConstant.MESSAGE_NOTIFY_KEY,
            true);

    String notifyId =
        (String) SPUtils.get(MyApplication.getInstance(), SpKeyConstant.MESSAGE_NOTIFY_ID_KEY, "");
    boolean isRing = true;
    if (null != MyApplication.getInstance().getUserInfo()) {
      if (MyApplication.getInstance().getUserInfo().getUserId().equals(notifyId)
          && !isNotify) {
        isRing = false;
        channelId = channelId2;
      }
    }

    if (isRing) {
      AudioManager audioManager =
          (AudioManager) MyApplication.getInstance().getSystemService(Context.AUDIO_SERVICE);
      audioManager.setMode(AudioManager.MODE_NORMAL);
      channelId = channelId1;
    }

    if (Foreground.get().isForeground()) {
      String id =
          (String) SPUtils.get(MyApplication.getInstance(), SpKeyConstant.CHAT_IDENTIFY_KEY, "");

      if (!TextUtils.isEmpty(id) && id.equals(msg.getConversation().getPeer())) {
        return;
      }

      String tabPosition =
          (String) SPUtils.get(MyApplication.getInstance(), SpKeyConstant.HOME_TAB_KEY, "");
      if (tabPosition.equals("0")) {
        if (isRing) {
          Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
          Ringtone r = RingtoneManager.getRingtone(MyApplication.getInstance(), notification);
          r.play();
        }
        Vibrator vibrator =
            (Vibrator) MyApplication.getInstance().getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(new long[] { 0, 400, 100, 400 }, -1);
        return;
      }
    }
    String senderStr, contentStr;
    NotificationCompat.Builder builder;
    Message message = MessageFactory.getMessage(msg);
    if (message == null) return;
    TIMConversation conversation = message.getMessage().getConversation();
    if (conversation.getType() == TIMConversationType.Group) {
      senderStr = GroupInfo.getInstance().getGroupName(conversation.getPeer());
    } else {
      if (FriendshipInfo.getInstance().isFriend(message.getSender())) {
        senderStr = FriendshipInfo.getInstance().getProfile(message.getSender()).getName();
      } else {
        senderStr = message.getSender();
      }
    }
    contentStr = message.getSummary();
    NotificationManager mNotificationManager = (NotificationManager) MyApplication.getInstance()
        .getSystemService(MyApplication.getInstance().NOTIFICATION_SERVICE);

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
      NotificationChannel notificationChannel =
          mNotificationManager.getNotificationChannel(channelId);
      if (notificationChannel == null) {
        int importance = NotificationManager.IMPORTANCE_HIGH;
        notificationChannel = new NotificationChannel(channelId, channelDescription, importance);
        notificationChannel.enableLights(true);
        notificationChannel.setLightColor(Color.GREEN);
        notificationChannel.enableVibration(true);
        if (!isRing) {
          notificationChannel.setSound(null, null);
          deleteNoNumberNotification(mNotificationManager,channelId1);
        }else {
          deleteNoNumberNotification(mNotificationManager,channelId2);
        }
        mNotificationManager.createNotificationChannel(notificationChannel);
      }
      builder =
          new NotificationCompat.Builder(MyApplication.getInstance(), channelId);
    } else {
      builder =
          new NotificationCompat.Builder(MyApplication.getInstance());
    }

    Intent notificationIntent = new Intent(MyApplication.getInstance(), NotifyActivity.class);
    if (conversation.getType() == TIMConversationType.Group) {
      notificationIntent.putExtra(ChatActivity.TYPE_KEY, TIMConversationType.Group);
      notificationIntent.putExtra(ChatActivity.IDENTIFY_KEY, conversation.getPeer());
    } else {
      notificationIntent.putExtra(ChatActivity.TYPE_KEY, TIMConversationType.C2C);
      notificationIntent.putExtra(ChatActivity.IDENTIFY_KEY, message.getSender());
    }
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
        | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent intent = PendingIntent.getActivity(MyApplication.getInstance(), 0,
        notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    builder.setContentTitle(senderStr)//设置通知栏标题
        .setContentText(contentStr)
        .setContentIntent(intent) //设置通知栏点击意图
        //                .setNumber(++pushNum) //设置通知集合的数量
        .setTicker(senderStr + ":" + contentStr) //通知首次出现在通知栏，带上升动画效果的
        .setWhen(System.currentTimeMillis())//通知产生的时间，会在通知信息里显示，一般是系统获取到的时间
        .setChannelId(channelId)
        .setSmallIcon(R.mipmap.ic_launcher);//设置通知小ICON

    if (isRing) {
      builder.setDefaults(Notification.DEFAULT_ALL);
    } else {
      builder.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE);
    }
    Notification notify = builder.build();
    notify.flags |= Notification.FLAG_AUTO_CANCEL;
    mNotificationManager.notify(pushId, notify);
  }

  public void reset() {
    NotificationManager notificationManager = (NotificationManager) MyApplication.getInstance()
        .getSystemService(MyApplication.getInstance().NOTIFICATION_SERVICE);
    notificationManager.cancel(pushId);
  }

  /**
   * This method is called if the specified {@code Observable} object's
   * {@code notifyObservers} method is called (because the {@code Observable}
   * object has been updated.
   *
   * @param observable the {@link Observable} object.
   * @param data the data passed to {@link Observable#notifyObservers(Object)}.
   */
  @Override
  public void update(Observable observable, Object data) {
    if (observable instanceof MessageEvent) {
      if (data instanceof TIMMessage) {
        TIMMessage msg = (TIMMessage) data;
        if (msg != null) {
          PushNotify(msg);
        }
      }
      if (!Foreground.get().isForeground()) {
        int unreadNum = 0;
        List<TIMConversation> list = TIMManagerExt.getInstance().getConversationList();
        for (TIMConversation conversation : list) {
          if (conversation.getType() == TIMConversationType.System) continue;
          unreadNum += new NomalConversation(conversation).getUnreadNum();
        }
        ShortcutBadger.applyCount(MyApplication.getInstance(), unreadNum);
      }
    }
  }

  @RequiresApi(api = Build.VERSION_CODES.O)
  private static void deleteNoNumberNotification(NotificationManager nm, String newChannelId) {
    List<NotificationChannel> notificationChannels = nm.getNotificationChannels();
    if (null == notificationChannels ) {
      return;
    }
    for (NotificationChannel channel : notificationChannels) {
      if (channel.getId() == null || channel.getId().equals(newChannelId)) {
        continue;
      }

      int notificationNumbers = getNotificationNumbers(nm, channel.getId());
      if (notificationNumbers == 0) {
        nm.deleteNotificationChannel(channel.getId());
      }
    }
  }

  /**
   * 获取某个渠道下状态栏上通知显示个数
   *
   * @param mNotificationManager NotificationManager
   * @param channelId String
   * @return int
   */
  @RequiresApi(api = Build.VERSION_CODES.O)
  private static int getNotificationNumbers(NotificationManager mNotificationManager,
      String channelId) {
    if (mNotificationManager == null || TextUtils.isEmpty(channelId)) {
      return -1;
    }
    int numbers = 0;
    StatusBarNotification[] activeNotifications = mNotificationManager.getActiveNotifications();
    for (StatusBarNotification item : activeNotifications) {
      Notification notification = item.getNotification();
      if (notification != null) {
        if (channelId.equals(notification.getChannelId())) {
          numbers++;
        }
      }
    }
    return numbers;
  }
}
